﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using FourKillEnginePrototype.Properties;

namespace FourKill.Engine
{
    public class SpiralEffect : IPaintable
    {
        private static SpiralEffect _instance;
        private int _angle = 0;
        private int _angleTheta = 10;
        public static SpiralEffect Instance { get { _instance = _instance ?? new SpiralEffect(Color.Red,Color.Orange); return _instance; } }
        private Timer spiralTimer = new Timer();
        private Color _backgroundColor = Color.Red;
        private Color _alternatingColor = Color.Orange;
        private int _alpha = 255;
        private int _fadeStrength = 10;
        
        private FadeDirection _fadeDirection = FadeDirection.Out;

        public SpiralEffect(Color backgroundColor, Color alternatingColor)
        {
            _backgroundColor = backgroundColor;
            _alternatingColor = alternatingColor;
            spiralTimer.Interval = 100;
            spiralTimer.Enabled = true;
            spiralTimer.Tick += new EventHandler(spiralTimer_Tick);
        }

        void spiralTimer_Tick(object sender, EventArgs e)
        {
            _angle += 1;
            if (_angle > 359) _angle = 0;
            if (_fadeDirection == FadeDirection.Out)
            {
                _alpha = (_alpha - _fadeStrength > 0) ? _alpha - _fadeStrength : 0;
            }
            else
            {
                _alpha = (_alpha + _fadeStrength < 256) ? _alpha + _fadeStrength : 255;
            }
            if (_alpha == 0) _fadeDirection = FadeDirection.In;
            if (_alpha == 255) _fadeDirection = FadeDirection.Out;
        }

        double r = Math.PI / 180; // for radians
        public void Paint(IPaintableContext context)
        {
            Point center = new Point(context.ViewPort.PixelSize.Width / 2, context.ViewPort.PixelSize.Height / 2);
            int circleRadius = (context.ViewPort.PixelSize.Height > context.ViewPort.PixelSize.Width) ? context.ViewPort.PixelSize.Height : context.ViewPort.PixelSize.Width;

            //context.FrontLayer.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
            //context.FrontLayer.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            Color primary = Color.FromArgb(_alpha, _backgroundColor);
            Color secondary = Color.FromArgb(_alpha, _alternatingColor);

            context.FrontLayer.Clear(primary);

            using(var primaryBrush = new SolidBrush(primary))
            {
                context.FrontLayer.FillRectangle(primaryBrush, new Rectangle(0, 0, context.ViewPort.PixelSize.Width, context.ViewPort.PixelSize.Height));
            }

            using (var c1 = new SolidBrush(secondary))
            {
                int firstX, firstY, secondX, secondY;
                GraphicsPath gp = new GraphicsPath();
                for (int i = 0; i < 359; i += _angleTheta * 2)
                {
                    using (GraphicsPath triangle = new GraphicsPath())
                    {
                        firstX = (int)(center.X + circleRadius * Math.Cos((_angle + i) * r));
                        firstY = (int)(center.Y + circleRadius * Math.Sin((_angle + i) * r));

                        secondX = (int)(center.X + circleRadius * Math.Cos((_angle + i + _angleTheta) * r));
                        secondY = (int)(center.Y + circleRadius * Math.Sin((_angle + i + _angleTheta) * r));

                        triangle.AddLines(new Point[] { center,
                                                new Point(firstX, firstY),
                                                new Point(secondX, secondY) });
                        gp.AddPath(triangle, true);
                    }
                }

                using (var sb = new SolidBrush(secondary))
                {
                    context.FrontLayer.FillPath(sb, gp);
                }
                
            }           
        }
    }
}
